import time
import json
import urllib.parse

from wt.api_service.api_imp.database_api import DataBaseAPI
from wt.api_service.api_imp.project_api import ProjectAPI
from wt.auto_test_case.database_case import DatabaseCase
from wt.connector import workflow_func
from wt.init_param.task_init import TaskInit
# from wt.old_auto_test.auto_task_define.batch_task_create.batch_datasource_schema_next import BatchDatasourceSchemaNext
from wt.untils.common_until import CommonUntil
from wt.untils.decorators import Logger
from wt.api_service.api_imp.wt_task_api import WtTaskAPI


class WsTaskAPI(TaskInit):
    def __init__(self):
        super().__init__()
        self.wt_api = WtTaskAPI()
        self.logger = Logger("my")
        res_db_log = open(self.res_db_log, 'wb+', buffering=0)
        self.wt_request = workflow_func.WorkFlowExec(self.login_url, self.headers)
        self.wt_project = ProjectAPI(res_db_log)
        self.common_until = CommonUntil(res_db_log)
        # self.d_schema_next = BatchDatasourceSchemaNext(res_db_log)
        self.d_api = DataBaseAPI(res_db_log)
        self.t_case = DatabaseCase()

    def block_until_task_complete(self, project_name, task_name, task_type, total_timeout=20):
        start_time = time.time()
        elapsed_time = 0

        while True:
            # 检查任务状态
            if self.check_ws_task_state(project_name, task_name, task_type):
                print("任务已完成")
                return True
            # 计算已经过去的时间
            elapsed_time = time.time() - start_time

            # 检查超时
            if elapsed_time >= total_timeout:
                print("总时间已经用尽，任务未完成")
                return False
            # 等待一段时间后再次检查任务状态
            time.sleep(1)

            print("任务没有完成，继续等待ing")

    @Logger()
    def get_ws_define_process_code(self, project_name, task_name):
        project_code = self.wt_project.get_project_code(project_name)
        self.ws_task_search_json["searchVal"] = task_name
        self.ws_task_search_json["projectCodes"] = project_code

        res = self.wt_request.send_request(self.ws_workflow_define_url, "get", params=self.ws_task_search_json)
        tmp = self.common_until.get_res_json_value(res, "data")
        ws_process_code = tmp["totalList"][0]["code"]
        return ws_process_code



    @Logger()
    def get_ws_instance_task_info(self, project_name, task_name, col):
        """
        m.get_ws_instance_task_info("v26", "auto_psql_to_psql17", "state")
        :param project_name: v26 是项目
        :param task_name: auto_psql_to_psql17 工作流示例名称
        :param col: state 是需要获取的返回字段
        :return:
        """
        project_code = self.wt_project.get_project_code(project_name)

        self.ws_task_instance_search["searchVal"] = task_name
        self.ws_task_instance_search["projectCodes"] = project_code
        start_date = self.common_until.generate_time(0)
        end_date = self.common_until.generate_time(1)

        self.ws_task_instance_search["startDate"] = start_date
        self.ws_task_instance_search["endDate"] = end_date
        res = self.wt_request.send_request(self.ws_task_instance_url, "get", params=self.ws_task_instance_search)
        ws_instance_col = self.common_until.get_res_json_value(res, col)
        print(ws_instance_col)
        return ws_instance_col


    def check_ws_task_state(self, project_name, task_name, task_type):
        if task_type == 'BATCH':
            state = self.get_ws_instance_task_info(project_name, task_name, 'state')
            return state == 'SUCCESS'
        elif task_type == 'STREAMING':
            state = self.wt_api.get_wt_instance_task_info(project_name, task_name, task_type, 'state')
            time.sleep(2)
            return state == 'RUNNING_EXECUTION'

    @Logger()
    def run_ws_task(self, project_name, task_name, type, run_param=None):
        """

        :param project_name:
        :param task_name:
        :param type:
        :param run_param: ws 运行时的其他参数，例：补数 {scheduleTime:{"complementStartDate":"2024-07-09 00:00:00","complementEndDate":"2024-07-09 00:00:00","complementCalendarType":"NATURAL","complementCalendarCode":""}}
        :return:
        """
        project_code = self.wt_project.get_project_code(project_name)
        ws_define_process_code = self.get_ws_define_process_code(project_name, task_name)

        if run_param != None:
            for k, v in run_param.items():
                self.ws_task_run_json[k]=v

        if type == "BATCH":
            self.ws_task_run_json["processDefinitionCode"] = ws_define_process_code
            self.ws_task_run_json["projectCode"] = project_code
            res = self.wt_request.send_request(self.ws_run_url, "post", params=self.ws_task_run_json)
            self.common_until.get_res_is_success(res, "运行wt batch任务是否成功：")
        elif type == "STREAMING":
            wt_task_define_id = self.wt_api.get_wt_define_task_id(project_name, task_name)
            res = self.wt_request.send_request(self.wt_run_url, "post",
                                               params={"id": wt_task_define_id, "workflowCode": ws_define_process_code})
            self.common_until.get_res_is_success(res, "运行wt stream 任务是否成功：")
        return res.json()

    @Logger()
    def create_ws_task(self, project_name, task_name, wt_type):
        if wt_type == "BATCH":
            task_type = "WHALE_SEATUNNEL"
            task_execute_type = "BATCH"

            task_definition = self.ws_batch_task_definition
        elif wt_type == "STREAMING":
            task_type = "WHALETUNNEL_STREAM"
            task_execute_type = "STREAM"
            job_mode = "STREAMING"

            task_definition = self.ws_stream_task_definition
            task_definition["taskDefinitionJson"][0]["jobMode"] = job_mode
        else:
            print("请输入指定：wt_type: batch 或 stream")

        # 获取task_code、wt_task_id、wt_task_id等信息
        res = self.wt_request.send_request(self.ws_workflow_gen_task_codes_url, "get")
        task_code = self.common_until.get_res_json_value(res, "data")[0]
        wt_task_id = self.wt_api.get_wt_define_task_id(project_name, task_name)
        project_code = self.wt_project.get_project_code(project_name)

        # 替换变量
        task_definition["taskDefinitionJson"][0]["type"] = task_type
        task_definition["taskDefinitionJson"][0]["taskType"] = task_type  # WHALE_SEATUNNEL
        task_definition["taskDefinitionJson"][0]["taskExecuteType"] = task_execute_type

        task_definition["taskDefinitionJson"][0]["code"] = task_code
        task_definition["taskDefinitionJson"][0]["name"] = task_name
        task_definition["taskDefinitionJson"][0]["projectCode"] = project_code
        task_definition["taskDefinitionJson"][0]["taskParams"]["taskId"] = wt_task_id
        task_definition["taskRelationJson"][0]["postTaskCode"] = task_code
        task_definition["locations"][0]["taskCode"] = task_code

        form_data = {
            "taskDefinitionJson": json.dumps(task_definition["taskDefinitionJson"]),
            "taskRelationJson": json.dumps(task_definition["taskRelationJson"]),
            "locations": json.dumps(task_definition["locations"]),
            "name": task_name,
            "tenantCode": "default",
            "otherParamsJson": "{\"labelCodes\": \"\"}",
            "executionType": "PARALLEL",
            "description": "",
            "globalParams": [],
            "timeout": 0,
            "projectCode": project_code
        }

        res = self.wt_request.send_request(self.ws_workflow_define_url, "post", params=form_data)

        self.common_until.get_res_is_success(res, "创建ws任务是否成功：")
        return res.json()

    def delete_project_data(self, project_name, job_name=None):
        response_data = {'message': '', 'data': []}

        try:
            project_code_response = self.get_project_code(project_name)
            project_code = project_code_response['data']

            if project_code_response['message'] == "fail":
                response_data.update({'message': "fail", 'data': f'未找到该项目名称 {project_name}'})
                return response_data

            job_definitions_data = []

            batch_job_list = self.get_job_list(project_code, "BATCH")['data']['totalList']
            streaming_job_list = self.get_job_list(project_code, "STREAMING")['data']['totalList']
            job_list = batch_job_list + streaming_job_list
            workflow_list = self.get_workflow_list(project_code)['data']['totalList']

            form_data = {"jobDefinitions": job_definitions_data}

            if job_name is None:
                job_definitions_data.extend(
                    [{"projectCode": project_code, "jobDefinitionId": job['id']} for job in job_list])
                job_delete_response = self.wt_request.send_request(self.wt_job_delete, "post", json_data=form_data)
                job_delete = job_delete_response.json()

                workflow_codes = [workflow['code'] for workflow in workflow_list]
                if workflow_codes:
                    url = self.ws_workflow_batch_url + "?codes=" + ",".join(map(str, workflow_codes))
                    workflow_delete_response = self.wt_request.send_request(url, "DELETE")
                    workflow_delete = workflow_delete_response.json()
                    if job_delete['success'] and workflow_delete['success'] is True:
                        response_data.update({'message': "success", 'data': f'已清空项目 {project_name}'})
                else:
                    if job_delete['success']:
                        response_data.update({'message': "success", 'data': f'已清空项目 {project_name}'})
            else:
                job_definitions_data.extend(
                    [{"projectCode": project_code, "jobDefinitionId": job['id']} for job in job_list if
                     job['name'] == job_name])
                job_delete_response = self.wt_request.send_request(self.wt_job_delete, "post", json_data=form_data)
                job_delete = job_delete_response.json()

                workflow_codes = [workflow['code'] for workflow in workflow_list if workflow['name'] == job_name]
                if workflow_codes:
                    url = self.ws_workflow_batch_url + "?codes=" + ",".join(map(str, workflow_codes))
                    workflow_delete_response = self.wt_request.send_request(url, "DELETE")
                    workflow_delete = workflow_delete_response.json()
                    if job_delete['success'] and workflow_delete['success'] is True:
                        response_data.update({'message': "success", 'data': f'已清空项目 {project_name}' + (
                            f" 下的 {job_name} 任务" if job_name else "")})
                else:
                    if job_delete['success']:
                        response_data.update({'message': "success", 'data': f'已清空项目 {project_name}' + (
                            f" 下的 {job_name} 任务" if job_name else "")})
            return response_data
        except Exception as e:
            response_data.update({'message': "fail", 'data': f'未知错误: {str(e)}'})
            return response_data

    def get_workflow_list(self, project_code):
        response_data = {'message': '', 'data': []}
        try:
            other_params_json_decoded = urllib.parse.unquote(
                '%7B%22releaseState%22%3A%22%22%2C%22sortEnum%22%3A%22%22%7D')
            form_data = {
                "pageSize": 1000,
                "pageNo": 1,
                "otherParamsJson": other_params_json_decoded,
                "projectCodes": project_code
            }
            workflow_list_response = self.wt_request.send_request(self.ws_workflow_define_url, "GET", params=form_data)
            workflow_list = workflow_list_response.json()
            response_data.update({'message': "Success", 'data': workflow_list['data']})
        except Exception as e:
            response_data.update({'message': "fail", 'data': f'未知错误: {str(e)}'})
        return response_data

    def get_job_list(self, project_code, job_type):
        if self.sys_version == "2.6":
            form_data = {
                "pageSize": 1000,
                "pageNo": 1,
                "searchName": "",
                "jobMode": job_type,
                "projectCodes": project_code
            }
        elif self.sys_version == "2.7":
            form_data = {
                "schemaName": "",
                "taskName": "",
                "jobKey": "",
                "dateTimeType": "",
                "datePickerRange": "",
                "project": project_code,
                "global": "false",
                "searchName": "",
                "projectCodes": project_code,
                "jobMode": job_type,
                "pageNo": 1,
                "pageSize": 100
            }
        try:
            response_data = {'message': '', 'data': []}
            job_list_response = self.wt_request.send_request(self.wt_task_definition_url, "GET", params=form_data)
            job_list = job_list_response.json()
            response_data.update({'message': "Success", 'data': job_list['data']})
        except Exception as e:
            response_data.update({'message': "fail", 'data': f'未知错误: {str(e)}'})
        return response_data

    def get_project_code(self, project_name):
        response_data = {'message': '', 'data': []}
        try:
            form_data = {"pageSize": 1000, "pageNo": 1, "searchVal": ""}
            projects_list_response = self.wt_request.send_request(self.wt_projects_url, "GET", params=form_data)
            projects_list = projects_list_response.json()
            for project in projects_list['data']['totalList']:
                if project['name'] == project_name:
                    response_data.update({'message': "Success", 'data': project['code']})
                    return response_data
            response_data.update({'message': "fail", 'data': f'未找到该项目名称 {project_name}'})
        except Exception as e:
            response_data.update({'message': "fail", 'data': f'未知错误: {str(e)}'})
        return response_data


if __name__ == '__main__':
    m = WsTaskAPI()
    # m.get_wt_define_task_id("auto_test_project","100281_v26_fullread_batch_mysql_to_mysql")
